import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Common } from 'UtilsCommon';
import { useGetDataSourceOptions } from 'UseHooks';
import Base from './base';
import PropertyItem from './propertyItem';

const getOptions = (property, view, pageAxis, parentValue) => {
    const { dataSource } = property;
    if (!dataSource) return [];

    return dataSource.map(m => m);
};

const setRowData = (properties, rowData, id, property, pageAxis, rowView) => {
    const list = [];
    properties.forEach(p => {
        if (property.isReresh) p.id = Common.createGuid();
        p.id = p.id + id;
        p.dataId = id;
        p.data = rowData;
        p.isBind = true;

        if (p.name === property.checkBoxName) {
            rowData.getCheckBox = () => p;
            const primaryKey = property.primaryKey || 'Id';
            const item = Common.arrayFirst(property.selectOptions, f => f[primaryKey] === id);
            if (item) p.value = 1;
        }

        if (!Common.isNullOrEmpty(rowData[p.name])) p.value = rowData[p.name];
        if (property.expendSetData) {
            const fn = pageAxis.getFunction(property.expendSetData);
            fn && fn({ property, rowView, p, rowData });
        }
        if (p.linkUrl) p.linkUrl = Common.replaceDataContent(rowData, p.linkUrl, true);

        if (p.properties) setRowData(p.properties, rowData, id, property, pageAxis, rowView);
    });
    return list;
};

const renderColumn = (p, i, property, pageId) => {
    return <td key={i} width={p.width}>{Base.getPropertyItem(p, property, pageId)}</td>;
};

const getTbody = (ele) => {
    if (ele.nodeName.toLowerCase() === "tbody") return ele;
    else return getTbody(ele.parentNode);
};

const getTr = (ele) => {
    if (ele.nodeName.toLowerCase() === "tr") return ele;
    else return getTr(ele.parentNode);
};

const setTrSelected = (e) => {
    const tbody = getTbody(e.target);
    const tr = getTr(e.target);
    tbody.childNodes.forEach((m, i) => {
        if (m === tr) m.className = 'selected';
        else m.className = '';
    });
};

const renderRow = (m, index, property, pageId, pageAxis, onSelectClick) => {
    const primaryKey = property.primaryKey || 'Id';
    const id = m[primaryKey] || Common.createGuid();
    if (!m[primaryKey]) m[primaryKey] = id;

    const rowView = Common.clone(property.properties[0]);
    if (property.isReresh) rowView.id = Common.createGuid();
    rowView.id = rowView.id + id;
    if (rowView.properties) setRowData(rowView.properties, m, id, property, pageAxis, rowView);

    return <tr key={index} id={`tr_${id}`} onClick={(e) => {
        if (property.isSelected) setTrSelected(e);
        onSelectClick(m, e);
    }}>{rowView.properties.map((p, i) => renderColumn(p, i, rowView, pageId))}</tr>;
};

export default (props) => {
    const { property, pageAxis, view, pageId } = Base.getProps(props);

    const [options, setOptions] = useGetDataSourceOptions(property, view, pageAxis, getOptions, property.id);
    const [isVisible, setIsVisible] = useState(property.isVisible !== false);

    useMemo(() => {
        if (property.value) property.dataSource = property.value;
        property.selectOptions = [];
        if (property.properties.length === 2) {
            const [p1, p2] = property.properties;
            p2.properties.forEach((p, i) => { p1.properties[i].width = p.width; });
        }
    }, [property]);

    useEffect(() => {
        if (property.dataSourceChange) property.dataSourceChange(property.dataSource, property);
        property.isReresh = false;
    }, [property.dataSource]);

    const onSelectClick = useCallback((m, e) => {
        const isButtonClick = e.target.className && e.target.className.indexOf && e.target.className.indexOf('buttonActive') >= 0;
        if (!property.isSelected) return;

        const list = [];
        let blExists = false;
        const primaryKey = property.primaryKey || 'Id';
        property.selectOptions.forEach(d => {
            if (d[primaryKey] === m[primaryKey]) blExists = true;
            else list.push(d);
        });
        if (!blExists) list.push(m);
        else if (isButtonClick) return;

        const checkBox = m.getCheckBox ? m.getCheckBox() : null;
        if (checkBox) checkBox.setValue(blExists ? 0 : 1);
        property.selectOptions = list;
    }, [property]);

    property.setIsVisible = (v) => { property.isVisible = v; setIsVisible(v); };
    property.setValue = (v) => {
        property.dataSource = v;
        setOptions(getOptions(property, view, pageAxis));
    };
    property.refreshOptions = () => {
        property.isReresh = true;
        setOptions(getOptions(property, view, pageAxis));
    };

    if (!isVisible || property.isValueVisible) return null;

    const { style, tableClassName, tableStyle } = property;
    const theadProperty = property.properties.length === 2 ? property.properties[1] : null;

    return (
        <div style={Base.setStyle(style)}>
            <table style={Base.setStyle(tableStyle)} cellSpacing={0} cellPadding={0} className={tableClassName}>
                {theadProperty && <thead>
                    <tr>
                        {theadProperty.properties.map((m, i) => <th key={i} width={m.width}><PropertyItem property={m} view={theadProperty} pageId={pageId} /></th>)}
                    </tr>
                </thead>}
                <tbody>
                    {options.map((m, i) => renderRow(m, i, property, pageId, pageAxis, onSelectClick))}
                </tbody>
            </table>
        </div>
    );
};